// $Id: main.cpp 12 2009-05-04 19:51:42Z longerdev $

/*
Copyright (C) 2008 Longer <longerdev@gmail.com>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <getopt.h>
#include <dirent.h>
#include <errno.h>
#include "jt.h"
#include "confpath.h"

int killProc(std::string fn){
	FILE * fd;
	pid_t mypid;

	fd = fopen(fn.c_str(), "rt");
	if (fd){
		fread(&mypid, sizeof(pid_t), 1, fd);
		fclose(fd);
		unlink(fn.c_str());
	}
	else
		return 1;

	if (kill(mypid, SIGTERM) == -1)
		return 2;

	return 0;
}

int main(int argc, char* argv[]){
	if (argc == 1){
		Config conf;
		int secCount = conf.load(SYSCONFDIR"/jt.conf");
		if (secCount == -1){
			std::cerr << "jt.conf not exist!" << std::endl;
			exit(EXIT_FAILURE);
		}
		std::string cursec = "";
		std::string ex = "";

		for (int i = 0; i < secCount; i++){
			cursec = conf.getSection(i);
			if (cursec == "" || cursec == "global")
				continue;
			
			if (conf.isKey(cursec + "::active") && conf.getValue(cursec + "::active") == "1"){
				ex = "jt -s " + cursec;
				system(ex.c_str());
			}
		}

		return 0;
	}

	while (1){
		int option_index = 0;
		int c;

		option long_options[] = {
			{"section", required_argument, 0, 's'},
			{"kill", required_argument, 0, 'k'},
			{"help", no_argument, 0, 'h'},
			{"version", no_argument, 0, 'v'},
			{0, 0, 0, 0}
		};

		c = getopt_long(argc, argv, "s:k:hv", long_options, &option_index);
		if (c == -1)
			break;
			
		switch (c){
			case 's':{
				JT jt;

				jt.init(optarg);
				break;
			};
			
			case 'k':{
				Config conf;

				conf.load(SYSCONFDIR"/jt.conf");
				
				if (strncmp(optarg, "all", 3) == 0 && optarg[3] == 0){
					DIR *dh;
					if ((dh = opendir(conf.getValue("global::pid_path").c_str())) == NULL){
						std::cerr << "Error (" << errno << ") opendir " << conf.getValue("global::pid_path") << std::endl;
						exit(EXIT_FAILURE);
					}

					dirent *dir;
					while ((dir = readdir(dh)) != NULL){
						std::string sfn = dir->d_name;
						if ((sfn.substr(0, 3) ==  "jt_")
								&& (sfn.substr(sfn.length()-4, 4) == ".pid")){
							std::cout << "Kill " << sfn.substr(3, sfn.length()-7) << "... ";

							int errId = killProc(conf.getValue("global::pid_path") + sfn);
							if (errId == 0)
								std::cout << "OK" << std::endl;
							else
								std::cout << "Error (" << errId << ")" << std::endl;
						}
					}
					
					closedir(dh);
				}
				else{
					std::cout << "Kill " << optarg << "... ";

					int errId = killProc(conf.getValue("global::pid_path") + "jt_" + optarg + ".pid");
					if (errId == 0)
						std::cout << "OK" << std::endl;
					else
						std::cout << "Error (" << errId << ")" << std::endl;
				}

				break;
			};
			
			case 'h':
				std::cout << "Usage: jt [OPTION]\n\
Read config and start daemons with active=\"1\" (by default)\n\
 -s, --section=SECTION\tdaemon starting with selected section parametrs.\n\
 -k, --kill=SECTION\tkill selected daemon. (use 'all' to kill all)\n\
 -h, --help\t\tdisplay this\n\
 -v, --version\t\tdisplay version information" <<std::endl;
				return 0;

			case 'v':
				std::cout << "JIDs Tunnel " << VERSION << std::endl <<
				"Copyright (C) 2008 Longer <longerdev@gmail.com>\n\
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>" << std::endl;
				return 0;
				//break;
		}
	}

	return 0;
}

